package cryptage;

import DesInterface.DesPanel;

/**
 * Classe permettant de generer une clef
 * @author marie, margaux
 */
public class GenerationClef {
       
	/** Vecteur representant PC_1 de 56 bits*/
    private int[] store_num = new int[56];
    
    /** Vecteur representant PC_2 de 48 bits*/
    private int[] store_num1 = new int[48];
    
    /**
     * Table PC_1 : permuted choice 1
     */
    private int[][] PC_1 = {{57, 49, 41, 33, 25, 17,  9},
						    { 1, 58, 50, 42, 34, 26, 18},
						    {10,  2, 59, 51, 43, 35, 27},
						    {19, 11,  3, 60, 52, 44, 36},
						    {63, 55, 47, 39, 31, 23, 15},
						    { 7, 62, 54, 46, 38, 30, 22},
						    {14,  6, 61, 53, 45, 37, 29},
						    {21, 13,  5, 28, 20, 12, 4}};
    
    /**
     * Table PC_2 : permuted choice 2
     */
    private int[][] PC_2 = {{14, 17, 11, 24,  1,  5},
						    { 3, 28, 15,  6, 21, 10},
						    {23, 19, 12,  4, 26,  8},
						    {16,  7, 27, 20, 13,  2},
						    {41, 52, 31, 37, 47, 55},
						    {30, 40, 51, 45, 33, 48},
						    {44, 49, 39, 56, 34, 53},
						    {46, 42, 50, 36, 29, 32}};
    
    /**
     * 
     */
    private String keyS[][]= new String[7][8];
    
    /** Vecteur representant la partie gauche de la cle */
    private String leftKey[][] = new String [4][7];
    
    /** Vecteur representant la partie droite de la cle */
    private String rightKey[][] = new String [4][7];
    
    /**
     * 
     */
    private String finalS[][] = new String [6][8];
    
    
    /**
     * Constructeur : creation d'une instance de GenerationClef
     */
    public GenerationClef() {
        
    }
    
    /**
     * Remplissage du vecteur PC_1 a partir de la table PC_1
     */
    public void fillPermutedChoice1() {
        int index = 0;
        
        for (int row = 0; row < 8; row++) {
            for (int col = 0; col < 7; col++) {
                store_num[index] = PC_1[row][col];
                index++;
            }
        }
    }
    
    /**
     * Remplissage du vecteur PC_2 a partir de la table PC_2
     */
    public void fillPermutedChoice2() {
        int index = 0;
        
        for (int row = 0; row < 8; row++) {
            for (int col = 0; col < 6; col++) {
                store_num1[index] = PC_2[row][col];
                index++;
            }
        }
    }
    
    /**
     * Methode permettant de realiser le permuted choice 1 
     * @param key_in le vecteur cle en entree
     * @param key_out le vecteur cle en sortie
     */
    public void doPermutedChoice1(int[] key_in, int[] key_out) {
        int temp = 0;
        int i = 0;
        int loop = 0;
        int check = 0;
        
        while (check != 56) {
            temp = store_num[i];
            
            if (temp == loop) {
                key_out[check] = key_in[loop - 1];
                loop = 0;
                check++;
                i++;
            }
            loop++;
        }
        
        System.out.println("La cle de permutation :");
        
        for (int j = 0; j < key_out.length; j++) {
            System.out.print(key_out[j]);
        }
        
        int index = 0;
        for (int g = 0; g < 7; g++) {
            for (int j = 0; j < 8; j++) {
                keyS[g][j] = Integer.toString(key_out[index]);
                index++;
            }
        }
        
        DesPanel.printArray(keyS, "Apres permuted choice 1 :");
    }
    
    /**
     * Methode permettant de realiser le permuted choice 2
     * @param key_in le vecteur cle en entree
     * @param key_out le vecteur cle en sortie
     */
    public void doPermutedChoice2(int [] key_in, int [] key_out) {
        int temp = 0;
        int i = 0;
        int loop = 0;
        int check = 0;
        
        while (check != 48) {
            temp = store_num1[i];
            
            if (temp == loop) {
                key_out[check] = key_in[loop - 1];
                loop = 0;
                check++;
                i++;
            }
            loop++;
        }
        
        int index = 0;
        for (int g = 0; g < 6; g++) {
            for (int j = 0; j< 8; j++) {
            	finalS[g][j] = Integer.toString(key_out[index]);
                index++;
            }
        }
        
        DesPanel.printArray(finalS, "Apres permuted choice 2 :");
        //index=0;
    }
    
    /**
     * Methode permettant de separer la cle en deux parties, partie gauche C et partie droite D
     * @param key le vecteur cle initial
     * @param left le vecteur cle de la partie gauche
     * @param right le vecteur cle de la partie droite
     */
    public void doKeySegmentation(int[] key, int[] left, int[] right) {
        int index = 0;
        
        for (int i = 0; i < 28; i++)
            left[i] = key[i];
        
        for (int i = 28; i < 56; i++) {
            right[index] = key[i];            
            index++;
        }
                
        index = 0;
        
        for (int g = 0; g < 4; g++) {
            for (int j = 0; j < 7; j++) {
                leftKey[g][j] = Integer.toString(key[index]);
                index++;
            }
            
        }
        
        for (int g = 0; g < 4; g++) {
            for (int j = 0; j < 7; j++) {
                rightKey[g][j] = Integer.toString(key[index]);
                index++;
            }            
        }
        
        //index=0;
        
        DesPanel.printArray(leftKey, "Segmentation de la partie gauche de la cle :");
        DesPanel.printArray(rightKey, "Segmentation de la partie droite de la cle :");
    }
    
    /**
     * Methode permettant de faire un decalage a gauche
     * @param side1 la premiere partie de la cle
     * @param side2 la seconde partie de la cle
     */
    public void doOneLeftShift(int[] side1, int[] side2) {
        
        int temp = side1[0];
        
        for (int i = 1; i < side1.length; i++) {            
            side1[i - 1] = side1[i]; 
        }
        
        side1[side1.length - 1] = temp;
        temp = side2[0];
        
        for (int i = 1; i < side2.length; i++) {
            side2[i - 1] = side2[i];
        }
        
        side2[side2.length - 1] = temp;
        
        System.out.println("Apres un decalage a gauche :");
        
        for (int j = 0; j < side1.length; j++) {
            System.out.print(side1[j]);
        }
    }
}